//CONCUS (configuration and custom variables setup)
//part of the AXL (allegro XML based library) project
//by neil walker 2005

#ifndef axl_concus
#define axl_concus

#include "axl.h"

namespace AXL_Projects {
	//graphics mode. triple fails to paged, paged to double and system to double
	enum GraphicsRenderMode {MODE_TRIPLE=3, MODE_PAGED=2, MODE_SYSTEMDOUBLE=1, MODE_DOUBLE=0};
		
	class Configuration
	{
	public:
		Configuration(const std::string& filenameorxml);
		//initialise the configuration items
		//autowritebackmain means on destruction of config object all stored values
		//will be written back to disk except custom variables
		//autowritebackcustom means on destruction of config object all stored custom
		//values will be written back to disk

		~Configuration(void);

		std::string ConfigFile;

		//statics
		static void LogEntry(const std::string& entry,bool wipe=false, std::string filename="config.log");
		static std::string GlobalErrorString;			//last error in system

		//read a custom variable from the <custom> section of the xml file
		//reads from the internal vector
		//supports int, float, string, char*
		int GetCustom(const std::string& name,const int defaultvalue) const;
		float GetCustom(const std::string& name,const float defaultvalue) const;
		const std::string& GetCustom(const std::string& name, const std::string& defaultvalue) const;

		//as getcustom but for writing
		//just updates the local cache (vector array) unless an immediate flush is set
		void SetCustom(const std::string& name, const int value);
		void SetCustom(const std::string& name, const float value);
		void SetCustom(const std::string& name, const std::string& value);

		//write all custom variables to disk. called automatically on destruction
		//of the configuration object if the flag was set in the file
		bool FlushCustom(const std::string& filename=""); //default is to use ConfigFile set up by the loading of a config file or the manual setting of the name
		//as flushcustom but for flushmain
		bool FlushMain(const std::string& filename="");

		int AllegroStart();	//start up allegro using the allegro core details
							//leave in a graphics mode. 
							//return 0 if failed and system not set up
							//return 1 if set up exactly as read from XML
							//return 2 if set up but not exactly as the primary attributes
							
		//data available after configuration
		//some values can be altered on startup, e.g. the windowmode, whether sound was ok, etc
		//for these, an 'actual' struct exists
		//so that we can check the state but not necessarily alter the XML
		struct sSystem
		{
			int fps;
			bool DebugEnabled;
			bool UseMouse;
			bool UseJoystick;
			bool UseKeyboard;
			bool UseSound;
			bool UseMidi;
			bool AutoWriteMain;
			bool AutoWriteCustom;
			bool MatchRefreshRate;
		} CapsSystem;
			
		struct sGraphicsCaps
		{
			int ScrWidth;
			int ScrHeight;
			bool VSync;
			int Depth;
			int DepthFallback;
			std::string WindowMode;
			int WindowFallback;
			GraphicsRenderMode GraphicsMode;
			bool CapGraphicsToBufferType;
		} CapsGraphics;
		
		struct sSoundCaps
		{
			int SampleVolume;
			int MusicVolume;
			int MaxSounds;
		} CapsSound;
	
		struct sActualSystemStartup
		{
			bool UseSound;	//real answer after setting up
			bool UseMidi;	//real answer after setting up
			int DepthUsed; 	//real colour depth
			GraphicsRenderMode GraphicsMode;	//real mode set as may have failed - just check this against the CapsGraphics
		} CapsActualSystem;
		
		//8 bit requires a colour map for any blending work. Let's be nice
		COLOR_MAP game_colour_map;

		bool AllegroInitialised;	//indicates whether allegro is initialised so that the 
									//destructor can close everything down
		
	private:
		//data
		void Initialise(int fps, bool debugon,bool writemain, bool writecustom,
							 bool ejoy, bool ekey, bool emouse, bool esound, bool emidi,
							 bool vsync, int graphicsmode,int depthpreferred, int depthfallback,
							 int width, int height, const std::string& autodetectwindow, int fallbackwindow, 
							 int maxvoices, int soundvolume, int musicvolume,bool capgfx,bool matchrefreshrate=false);
		//store custom variables
		std::map<std::string,int> CustomInt;
		std::map<std::string,float> CustomFloat;
		std::map<std::string,std::string> CustomString;
		
	};
}
#endif
